import re
from typing import List

from c_model import FuncModel, ParamModel, UseFuncModel, CModel


func_pattern = r"""
    ([\w\s]*[\w\*]+)                       # 返回类型(可能包含空格和指针)
    \s+                                    # 至少一个空格
    (\w+)                                  # 函数名
    \s*                                    # 可能有空格
    \(                                     # 左括号
    ([^)]*)                                # 参数列表(可能为空)
    \)                                     # 右括号
    \s*                                    # 可能有空格
    \{                                     # 函数体开始
""".strip()

used_func_pattern = r"""
    (\w+)                                  # 函数名
    \s*                                    # 可能有空格
    \(                                     # 左括号
""".strip()

key_word = []

def get_cut_code(code, start_index, start_char, stop_char):
    """
    从源代码中截取pre_char, next_char中间的完整代码

    :param code: 源代码
    :param start_inex: 开始位置
    :param start_char: 开始字符
    :param stop_char: 结束字符
    :return:
    """
    cur_start, cnt = start_index, 1
    while code[cur_start] != start_char:
        cur_start += 1
    cur_start += 1
    while cnt != 0:
        if code[cur_start] == start_char:
            cnt += 1
        elif code[cur_start] == stop_char:
            cnt -= 1
        cur_start += 1
    return code[start_index: cur_start].strip()


def parse_param(params):
    # 处理参数列表
    param_list = []
    if not params:
        return []
    # 分割参数， 出来可能的复杂类型(如指针, 数组等)
    raw_params = [p.strip() for p in params.split(",")]
    for p in raw_params:
        param_parts = re.split(r"\s+", p.strip())
        if len(param_parts) >= 2:
            # 处理指针和数组类型
            param_list.append(ParamModel(" ".join(param_parts[:-1]), param_parts[-1]))
        elif param_parts:
            # 只有类型没有名称的参数
            param_list.append(ParamModel(param_parts[0], ""))
    return param_list

def parse_used_func(func_code):
    """
    从函数代码中提取调用的函数
    
    :param func_code: 函数代码
    :return:
    """
    result:List[UseFuncModel] = []
    for match in re.finditer(used_func_pattern, func_code, re.VERBOSE):
        func_name = match.group(1).strip()
        if func_name in key_word:
            continue
        param_code:str = get_cut_code(func_code, match.start(), "(", ")")
        result.append(UseFuncModel(func_name, param_code.replace(func_name, "")))
    return result[1:]


def parse_include(code):
    """
    解析导入的.h文件
    

    :param code: 代码内容
    :return:
    """
    return re.findall(r"#inclde [<\"]([\S^>^\"]+)[>\"]", code)

def parse_c_file(file_path):
    """
    解析C文件中的函数定义

    :param file_path: 文件路径
    :return:
    """
    with open(file_path, "r", encoding="utf-8") as f:
        content = f.read()
    
    # 移除单行和多行注释以减少干扰
    content = re.sub(r"[ ]*//.*?\n", "\n", content) # 移除单行注释
    content = re.sub(r"/\*.*?\*/", "", content, flags=re.DOTALL) # 移除多行注释
    inc_code = parse_include(content)
    func_models:List[FuncModel] = []
    for match in re.finditer(func_pattern, content, re.VERBOSE):
        name = match.group(2).strip()
        if name in key_word:
            continue
        func_code = get_cut_code(content, match.start(), "{", "}")
        func_model = FuncModel(
            name, 
            code = func_code,
            type=match.group(1).strip(),
            params = parse_param(match.group(3).strip()),
            funcs=parse_used_func(func_code)
        )
        func_models.append(func_model)
    return CModel(path=file_path, funcs=func_models, incs=inc_code)
